import store from '../store'
import { Message, MessageBox, Loading } from 'element-ui'
import { app } from '../main'
export default {
  /**
   * 参考：https://www.jianshu.com/p/d2f61e8795d2
   * Promise(承诺) 实现异步操作，一共有三种状态，分别为pending（进行中）、fulfilled（已成功）和rejected（已失败）
   *(1)只有异步操作可以决定当前处于的状态，并且任何其他操作无法改变这个状态；
   * (2)一旦状态改变，就不会在变。状态改变的过程只可能是：从pending变为fulfilled和从pending变为rejected。如果状态发生上述变化后，此时状态就不会在改变了，这时就称为resolved（已定型）
   * Promise.resolve(value)返回一个以给定的值解析后的Promise对象
   * Vue.nextTick用于延迟执行一段代码 //https://www.jianshu.com/p/a7550c0e164f
   *
   * 显示弹窗的方法
   * @param {string} title 弹窗标题
   * @param content 弹窗内容
   * @param options // 其他选择，透传给element
   * @example
   * 简单方式：dialog('标题', '内容')
   * 弹出组件：dialog('标题', Component)
   * 弹出JSX：dialog('标题', (h) => <Component data={this.data}></Component>)
   */
  dialog (title, content, options = {}) {
    const dialog = {
      title,
      content: { name: 'dialog-content', render: (h) => typeof content === 'string' ? h('span', content) : content },
      visible: true,
      options
    }
    store.commit('updateDialog', dialog)
    return new Promise(resolve => {
      app.$nextTick(() => {
        const dialogCom = app?.$children[0]?.$children[0]?.$refs.osDialog
        const contentCom = dialogCom.$refs.content?.$children[0]
        resolve({ dialog: dialogCom, component: contentCom })
      })
    })
  },
  hideDialog () {
    store.commit('hideDialog')
  },
  // 消息框简单封装
  message: {
    base (message, type, duration = 3000) {
      Message.closeAll()
      Message({ message, type, duration })
    },
    // success/warning/info/error
    success (message, duration = 3000) {
      this.base(message, 'success', duration)
    },
    warning (message, duration = 3000) {
      this.base(message, 'warning', duration)
    },
    info (message, duration = 3000) {
      this.base(message, 'info', duration)
    },
    error (message, duration = 3000) {
      this.base(message, 'error', duration)
    }
  },
  loading: {
    instance: null,
    tabInstance: {},
    open (text, target) {
      this.close()
      this.instance = Loading.service({ lock: true, text, target })
    },
    openInTab (text) {
      const activeTab = store.state.activeTab
      const id = '#pane-' + activeTab
      this.closeInTab()
      this.tabInstance[id] = Loading.service({ lock: true, text, target: id })
    },
    closeInTab () {
      const activeTab = store.state.activeTab
      const id = '#pane-' + activeTab
      if (this.tabInstance[id]) {
        this.tabInstance[id].close()
        this.tabInstance[id] = null
      }
    },
    close () {
      this.instance && this.instance.close()
    }
  },
  // alert
  alert (content, title = '提示信息', options) {
    return new Promise((resolve) => {
      MessageBox.alert(content, title, {
        // type: 'info',
        ...options
      }).then(() => resolve(true)).catch(() => resolve(false))
    })
  },
  confirm (content, title = '确认操作', options) {
    return new Promise((resolve) => {
      MessageBox.confirm(content, title, {
        // type: 'warning',
        ...options
      }).then(() => resolve(true)).catch(() => resolve(false))
    })
  },
  formOptions (labelWidth = 160, span = 8) {
    return {
      submitBtn: false,
      resetBtn: false,
      row: { type: 'flex' },
      global: {
        '*': {
          col: { span },
          props: { clearable: true }
        }
      },
      form: {
        labelSuffix: ':',
        labelWidth: labelWidth + 'px'
      }
    }
  },
  /**
   * 设置动态下拦框项
   * @param {*} fApi createform
   * @param {*} prop 字段名称
   * @param {*} params 字段值
   * @param {*} labelKey 下拉显示值
   * @param {*} valueKey 下拉框值
   * @param {*} action 访问数据URL
   * @returns
   */
  setOptions: async (fApi, prop, labelKey = 'label', valueKey = 'value', action = 'system/getDictItemCode', params = {}) => {
    const re = await store.dispatch(action, params)
    const data = re.data === undefined ? re : re.data
    if (data) {
      let options = data?.records || data || []
      const res = options
      if (labelKey !== 'label' || valueKey !== 'value') {
        options = options.map(item => ({ label: item[labelKey], value: item[valueKey] }))
      }
      const rule = { options: options }
      fApi.updateRule(prop, rule, true)
      return { data, res, options }
    }
    return {}
  },
  updateFormProps (fApi, prop, values) {
    fApi.updateRule(prop, { props: values })
  },
  updateFormOptions (fApi, prop, options) {
    fApi.updateRule(prop, { options }, true)
  },
  download (url, fileName) {
    const link = document.createElement('a')
    link.style.display = 'none'
    link.href = url
    fileName && link.setAttribute('download', fileName)

    document.body.appendChild(link)
    link.click()
    URL.revokeObjectURL(link.href)
    document.body.removeChild(link)
  },
  transformPromise (fApi) {
    const arr = Array.isArray(fApi) ? fApi : [fApi]
    const ps = arr.map(fapi => {
      return new Promise((resolve, reject) => {
        fapi.validate((v) => {
          if (v) resolve(v)
        })
      })
    })
    return Array.isArray(fApi) ? ps : ps[0]
  }
}
